#include "gerror.h"
#include "log.h"
#include <frameobject.h>
#include <sstream>
#include <cstdlib>

using namespace std;

PythonError::PythonError(string err) throw () :
		GError(err)
{
	if (PyErr_Occurred())
	{
		if (PyErr_ExceptionMatches(PyExc_SystemExit))
			exit(1);

		PyObject *pType, *pValue, *pTraceback;
		PyErr_Fetch(&pType, &pValue, &pTraceback);
		PyTracebackObject* traceback = (PyTracebackObject*) pTraceback;

		int line;
		const char* filename;
		if (traceback != NULL)
		{
			line = traceback->tb_lineno;
			filename = PyString_AsString(
					traceback->tb_frame->f_code->co_filename);
		}
		PyObject *pAttr = PyObject_GetAttrString(pType, "__name__");
		const char* name = PyString_AsString(pAttr);
		const char* value = PyString_AsString(pValue);

		ostringstream ss;
		ss << err << ":\n";
		if (traceback != NULL)
			ss << filename << ":" << line << "  ";
		ss << name << ": " << value;
		msg = ss.str();

		Py_XDECREF(pAttr);
		Py_XDECREF(traceback);
		Py_XDECREF(pType);
		Py_XDECREF(pValue);
		Py_XDECREF(pTraceback);
	}
	msg = string("PythonError: ") + msg;
}

void pythonError(PyObject *obj, std::string msg)
{
	if (obj == NULL || PyErr_Occurred())
	{
		throw PythonError(msg);
	}
}
